package csc.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 
 * @author Stanislau Dubrouski
 */
public class Utils {

    /**
     * Concats two arrays
     * @param a
     * @param b
     * @return concationation result
     */
    public static float[][] concatArrays(float[][] a, float[][] b) {
        int aLen = a.length;
        int bLen = b.length;
        float[][] C = new float[aLen + bLen][];
        System.arraycopy(a, 0, C, 0, aLen);
        System.arraycopy(b, 0, C, aLen, bLen);
        return C;
    }

    /**
     * Computes mean value of numbers in input list
     * @param input
     * @return mean value of numbers in input
     */
    public static float computeMeanValue(Collection<Float> input) {
        float sum = 0;
        if (!input.isEmpty()) {
            for (Float f : input) {
                sum += f;
            }
            return sum / input.size();
        }
        return sum;
    }

    /**
     * Computes standart deviation of numbers in input list
     * @param input
     * @return standart deviation of numbers in input
     */
    public static float computeStandartDeviation(Collection<Float> input) {
        return (float) Math.sqrt(Utils.computeVariance(input));
    }

    /**
     * 
     * @param input
     * @return variance of numbers in input
     */
    public static float computeVariance(Collection<Float> input) {
        if (input.size() < 2) {
            throw new IllegalArgumentException("Input list cannot contain less than 2 items!");
        }
        float sum = 0;
        float mean = Utils.computeMeanValue(input);
        for (Float f : input) {
            sum += (f - mean) * (f - mean);
        }
        return sum / (input.size() - 1);
    }

    /**
     * Removes null values from list
     * @param <E>
     * @param input
     * @return list without null values
     */
    public static <E> List<E> removeNullValues(Collection<E> input) {
        List<E> result = new ArrayList<E>();
        for (E object : input) {
            if (object == null) {
                continue;
            }
            result.add(object);
        }
        
        List<E> unmodifResult = new ArrayList<E>();
        unmodifResult.addAll(Collections.unmodifiableList(result));
        
        return unmodifResult;
    }
   
}
